-module(tableau).
-include_lib("tableau.hrl").

%% ====================================================================
%% API functions
%% ====================================================================
-export([
         init/2,
         getD/2,
         setD/3,
         getPi/2,
         setPi/3,
         print/2
]).


%% ====================================================================
%% External exports
%% ====================================================================

init(VertexList, Vertex_ID) ->
    Tableau = initTableau(VertexList, #tableau{}),
    case orddict:find(Vertex_ID, Tableau#tableau.d) of
        {ok, _Value} -> TL = orddict:erase(Vertex_ID, Tableau#tableau.d),
                        Tableau#tableau{
                                          d = orddict:append(Vertex_ID, 0, TL)
                                         };
        error        -> false
    end.


getD(Tableau, Vertex_ID) ->
    case orddict:find(Vertex_ID, Tableau#tableau.d) of
        {ok, Value} -> [Result] = Value, Result; 
        error        -> false

    end.

setD(Tableau, Vertex_ID, D) ->
    case orddict:find(Vertex_ID, Tableau#tableau.d) of
        {ok, _Value} -> TL = orddict:erase(Vertex_ID, Tableau#tableau.d),
                       Tableau#tableau{
                                          d = orddict:append(Vertex_ID, D, TL)
                                       };
        error        -> false
    end.

getPi(Tableau, Vertex_ID) ->
  case orddict:find(Vertex_ID, Tableau#tableau.pi) of
        {ok, Value} -> [Result] = Value, Result; 
        error        -> false
    end.

setPi(Tableau, Vertex_ID, Pi) ->
  case orddict:find(Vertex_ID, Tableau#tableau.pi) of
        {ok, _Value} -> TL = orddict:erase(Vertex_ID, Tableau#tableau.pi),
                       Tableau#tableau{
                                          pi = orddict:append(Vertex_ID, Pi, TL)
                                       };
        error        -> false
    end.

print(Graph, Tableau) ->
    P = fun(Key, Value) -> String = string:concat(atom_to_list('vertex '), atom_to_list(graph:getValV(Graph, Key, 'name'))),
                           String1 = string:concat(String, atom_to_list(' value ')),
                           [V] = Value,
                           String2 = string:concat(String1, "V"),
                           io:write(list_to_atom(String2)),
                           io:nl() end,
    orddict:map(P, Tableau#tableau.d).

%% ====================================================================
%% Internal functions
%% ====================================================================

%% Graphentheorethische Kontepte und Algorithmen. Seite 172
initTableau([], Tableau) ->
    Tableau;
initTableau(VertexList, Tableau) ->
    [Vertex | Tail] = VertexList,
    Tableau_New = Tableau#tableau{
                                     %% TODO RICHTIG KACKE Warum gibts kein MAX_INT?!?
                                     d = orddict:append(Vertex, 999999, Tableau#tableau.d),
                                     pi = orddict:append(Vertex, nil, Tableau#tableau.pi)
                                     },
    initTableau(Tail, Tableau_New).
